package com.example.demo.controller;

import com.example.demo.common.ArticleComparator;
import com.example.demo.common.ResultAjax;
import com.example.demo.common.SessionUtils;
import com.example.demo.model.Articleinfo;
import com.example.demo.model.DiscussInfo;
import com.example.demo.model.ReplyInfo;
import com.example.demo.model.Userinfo;
import com.example.demo.model.vo.ArticleinfoVO;
import com.example.demo.model.vo.ReplyInfoVO;
import com.example.demo.model.vo.UserinfoVO;
import com.example.demo.service.ArticleService;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

@RestController
@RequestMapping("/art")
public class ArticleController {
    private static final int _DESC_LENGTH = 100;    // 文章简介长度

    @Autowired
    private ArticleService articleService;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @Autowired
    private UserService userService;

    /**
     * 作者查看自己的文章
     * @param request
     * @return
     */
    @RequestMapping("/mylist")
    public ResultAjax myList(HttpServletRequest request) {
        // 1. 得到当前登录用户
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-2,"请登录！");
        }

        // 2. 根据用户 id 查询此用户发表的所有文章
        List<Articleinfo> list = articleService.getListByUid(userinfo.getId());
        // 处理 list：将文章正文变成简介
        if (list != null && list.size() > 0) {
            // 并发处理 list
            list.stream().parallel().forEach((art)->{
                // 设置简介 显示
                if (art.getContent().length() > _DESC_LENGTH) {
                    art.setContent(art.getContent().substring(0,_DESC_LENGTH));
                }
            });
        }
        // 3. 返回给前端
        return ResultAjax.succ(list);
    }


    /**
     * 删除文章
     */
    @RequestMapping("/del")
    public ResultAjax del(Integer aid, HttpServletRequest request) {
        // 1. 参数效验
        if (aid == null || aid <= 0) {
            return ResultAjax.fail(-1,"参数错误！");
        }
        // 2. 得到当前登录的用户
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-2,"请先登录！");
        }
        // 3. 判断文章的归属人+删除操作
        int result = articleService.del(aid, userinfo.getId());

        // 4. 将结果返回给前端
        return ResultAjax.succ(result);
    }


    /**
     * 申请发表文章
     */
    @RequestMapping("/add")
    public ResultAjax add(ArticleinfoVO articleinfoVO, HttpServletRequest request) {
        // 1. 效验参数
        if (articleinfoVO == null || !StringUtils.hasLength(articleinfoVO.getTitle()) ||
                !StringUtils.hasLength(articleinfoVO.getContent())) {
            return ResultAjax.fail(-1,"非法参数");
        }
        // 2. 组装数据(获取当前用户信息，将用户 id 和 用户名（用于后面管理员功能） 组装)
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-2,"请先登录");
        }
        articleinfoVO.setUser(userinfo.getUsername());
        articleinfoVO.setUid(userinfo.getId());
        // 3. 将数据入库
        int result = articleService.add(articleinfoVO);
        // 4. 结果返回给前端
        return ResultAjax.succ(result);
    }



    /**
     * 查看自己发表的文章
     */
    @RequestMapping("/update_init")
    public ResultAjax updateInit(Integer aid, HttpServletRequest request) {
        // 1. 参数效验
        if (aid == null || aid <= 0) {
            return ResultAjax.fail(-1,"参数有误!");
        }
        // 2. 得到当前登录用户的 id
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-2,"请先登录!");
        }
        // 3. 查询文章并效验权限 where id = #{aid} and uid = #{uid}
        Articleinfo articleinfo = articleService.getArticleByAndUid(aid, userinfo.getId());
        // 4. 将结果返回给前端
        return ResultAjax.succ(articleinfo);
    }


    /**
     * 修改文章信息
     */
    @RequestMapping("/update")
    public ResultAjax update(Articleinfo articleinfo, HttpServletRequest request) {
        // 1. 参数效验
        if (articleinfo == null || !StringUtils.hasLength(articleinfo.getTitle()) ||
                !StringUtils.hasLength(articleinfo.getContent()) || articleinfo.getId() == 0) {
            return ResultAjax.fail(-1,"非法参数！");
        }
        // 2. 获取登录用户 并组装
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-2,"请先登录！");
        }
        articleinfo.setUid(userinfo.getId());
        LocalDateTime dateTime = LocalDateTime.now();
        articleinfo.setUpdatetime(dateTime);
        // 3. 修改文章，并效验归属人
        int result = articleService.update(articleinfo);
        // 4. 返回结果
        return ResultAjax.succ(result);
    }


    /**
     * 查看文章详情
     */
    @RequestMapping("/detail")
    public ResultAjax detail(Integer aid) throws ExecutionException, InterruptedException {
        // 1. 参数效验
        if (aid == null || aid <= 0) {
            return ResultAjax.fail(-1,"非法参数！");
        }
        // 2. 查询文章详情
        Articleinfo articleinfo = articleService.getArticleById(aid);
        if (articleinfo == null || articleinfo.getId() <= 0) {
            return ResultAjax.fail(-1,"非法参数！");
        }
        // 3. 根据 uid 查询用户的信息
        FutureTask<UserinfoVO> userTask = new FutureTask<>(()->{
            // 返回用户信息
            return userService.getUserById(articleinfo.getUid());
        });
        taskExecutor.submit(userTask);
        // 4. 根据 uid 查询用户发表的总文章数
        FutureTask<Integer> artCountTask = new FutureTask<>(()->{
           // 返回文章总数
            return articleService.getArtCountByUid(articleinfo.getUid());
        });
        taskExecutor.submit(artCountTask);
        // 5. 组装数据
        UserinfoVO userinfoVO = userTask.get();  // 等待任务（线程池）执行完成
        int artCount = artCountTask.get();  // 等待任务（线程池）执行完成
        userinfoVO.setArtCount(artCount);
        HashMap<String,Object> result = new HashMap<>();
        result.put("user",userinfoVO);
        result.put("art",articleinfo);
        // 6. 返回结果给前端
        return ResultAjax.succ(result);
    }


    /**
     * 阅读量
     * @param aid
     * @return
     */
    @RequestMapping("/increment_rcount")
    public ResultAjax incrementRCount(Integer aid) {
        // 1. 效验参数
        if (aid == null || aid <= 0) {
            return ResultAjax.fail(-1,"参数有误！");
        }
        // 2. 更改数据库  update articleinfo set rcount = rcount + 1 where aid = #{aid}
        int result = articleService.incrementRCount(aid);
        // 3. 返回结果
        return ResultAjax.succ(result);
    }


    /**
     * 查询分页功能
     */
    @RequestMapping("/getlistbypage")
    public ResultAjax getListByName(Integer psize, Integer pindex) throws ExecutionException, InterruptedException {
        // 1. 参数校正
        if (pindex == null  || pindex < 1) {
            pindex = 1;
        }
        if (psize == null || psize < 1) {
            psize = 3;
        }
        // 2. 并发进行 文章分页列表查询 和 总页数的查询
        // (2.1) 文章分页列表查询
        int finalPSize = psize;
        int finalPIndex = pindex;
        int offset = finalPSize * (finalPIndex - 1);
        FutureTask<List<Articleinfo>> listTask = new FutureTask<>(()->{
            return articleService.getListByPage(finalPSize,offset);
        });
        taskExecutor.submit(listTask);
        // (2.2) 总页数的查询
        FutureTask<Integer> sizeTask = new FutureTask<>(()->{
            // 得到总的文章条数
            int totalCount = articleService.getCount();
            double sizeTemp = (totalCount * 1.0) / (finalPSize * 1.0);
            // 向上取整返回
            return (int)Math.ceil(sizeTemp);
        });
        taskExecutor.submit(sizeTask);
        // 3. 组装数据
        List<Articleinfo> list = listTask.get();
        // 并发处理 list
        list.stream().parallel().forEach((art)->{
            // 设置简介 显示
            if (art.getContent().length() > _DESC_LENGTH) {
                art.setContent(art.getContent().substring(0,_DESC_LENGTH));
            }
        });


        int size = sizeTask.get();
        HashMap<String,Object> map = new HashMap<>();
        map.put("list",list);
        map.put("size",size);
        // 4. 结果返回给前端
        return ResultAjax.succ(map);
    }


    /**
     * 修改书籍信息
     * @return
     */
    @RequestMapping("/updatebook")
    public ResultAjax updateBook(Articleinfo articleinfo) {
        if (articleinfo == null) {
            return ResultAjax.fail(-1,"参数错误");
        }

        Articleinfo art = articleService.getArticleById(articleinfo.getId());
        if (art == null) {
            return ResultAjax.fail(-1,"文章不存在");
        }
        if (!StringUtils.hasLength(articleinfo.getTitle()) && !StringUtils.hasLength(articleinfo.getType())
                && StringUtils.hasLength(articleinfo.getTime())) {
            articleinfo.setTitle(art.getTitle());
            articleinfo.setType(art.getType());
        }

        if (!StringUtils.hasLength(articleinfo.getTitle()) && StringUtils.hasLength(articleinfo.getType())
                && StringUtils.hasLength(articleinfo.getTime())) {
            articleinfo.setTitle(art.getTitle());
            articleinfo.setTime(art.getTime());
        }
        if (StringUtils.hasLength(articleinfo.getTitle()) && !StringUtils.hasLength(articleinfo.getType())
                && !StringUtils.hasLength(articleinfo.getTime())) {
            articleinfo.setTime(art.getTime());
            articleinfo.setType(art.getType());
        }
        if (StringUtils.hasLength(articleinfo.getTitle()) &&  StringUtils.hasLength(articleinfo.getType())
                && !StringUtils.hasLength(articleinfo.getTime())) {
            articleinfo.setTime(art.getTime());
        }
        if (StringUtils.hasLength(articleinfo.getTitle()) && !StringUtils.hasLength(articleinfo.getType())
                && StringUtils.hasLength(articleinfo.getTime())) {
            articleinfo.setType(art.getType());
        }
        if (!StringUtils.hasLength(articleinfo.getTitle()) && StringUtils.hasLength(articleinfo.getType() )
                && StringUtils.hasLength(articleinfo.getTime())) {
            articleinfo.setTitle(art.getTitle());
        }
        if (!StringUtils.hasLength(articleinfo.getTitle()) && !StringUtils.hasLength(articleinfo.getType() )
                && !StringUtils.hasLength(articleinfo.getTime())) {
            return ResultAjax.succ(2);
        }
        LocalDateTime dateTime = LocalDateTime.now();
        articleinfo.setUpdatetime(dateTime);
        int result = articleService.updateBook(articleinfo);
        return ResultAjax.succ(result);
    }


    /**
     * 搜索功能
     * @param articleinfo
     * @return
     */
    @RequestMapping("/search")
    public ResultAjax search(ArticleinfoVO articleinfo) {
        if (userService == null) {
            return ResultAjax.fail(-1,"参数错误");
        }
        List<Articleinfo> list = new ArrayList<>();
        if (StringUtils.hasLength(articleinfo.getTitle())) {
            list = articleService.getArticleByTitle(articleinfo.getTitle());
        }
        if (StringUtils.hasLength(articleinfo.getType())) {
            list = articleService.getArticleByType(articleinfo.getType());
        }
        if (StringUtils.hasLength(articleinfo.getTime())) {
            list = articleService.getArticleByTime(articleinfo.getTime());
        }
        if (StringUtils.hasLength(articleinfo.getUser())) {
            Userinfo userinfo = userService.getUserByName(articleinfo.getUser());
            list = articleService.getListByUid(userinfo.getId());
        }

        if (list != null && list.size() > 0) {
            // 并发处理 list
            list.stream().parallel().forEach((art)->{
                // 设置简介 显示
                if (art.getContent().length() > _DESC_LENGTH) {
                    art.setContent(art.getContent().substring(0,_DESC_LENGTH));
                }
            });
        }

        return ResultAjax.succ(list);
    }


    /**
     * 初始化评论列表
     * @param aid
     * @return
     */
    @RequestMapping("/discuss")
    public ResultAjax discussList(Integer aid) {
        // 1. 参数效验
        if (aid == null || aid <= 0) {
            return ResultAjax.fail(-1,"非法参数！");
        }
        // 2. 查询文章详情
        Articleinfo articleinfo = articleService.getArticleById(aid);
        if (articleinfo == null || articleinfo.getId() <= 0) {
            return ResultAjax.fail(-1,"非法参数！");
        }
        // 处理简介
        if (articleinfo.getContent().length() > _DESC_LENGTH) {
            articleinfo.setContent(articleinfo.getContent().substring(0,_DESC_LENGTH));
        }
        // 3. 查询评论和里面的回复集合
        List<DiscussInfo> discussList = articleService.getDiscussByAid(aid);
        for (int i = 0; i < discussList.toArray().length; i++) {
            List<ReplyInfo> replyList = articleService.getReplyByDid(discussList.get(i).getId());
            discussList.get(i).setReplyList(replyList);
        }
        // 4. Hash 表键值对返回，前端展示
        HashMap<String,Object> result = new HashMap<>();
        result.put("discuss",discussList);
        result.put("art",articleinfo);
        System.out.println(result);
        // 5. 返回前端
        return ResultAjax.succ(result);
    }


    /**
     * 评论
     * @param discussInfo 评论对象
     * @return ResultAjax
     */
    @RequestMapping("/dodiscuss")
    public ResultAjax doDiscuss(DiscussInfo discussInfo,HttpServletRequest request) {
        // 1. 效验参数
        if (discussInfo == null) {
            return ResultAjax.fail(-1,"参数错误");
        }
        // 2. 获取当前用户
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-2,"请先登录");
        }
        System.out.println(userinfo.toString());
        // 3. 组装数据
        discussInfo.setUser(userinfo.getUsername());
        // 4. 插入数据库,返回
        int result = articleService.doDiscuss(discussInfo);
        return ResultAjax.succ(result);
    }


    /**
     * 回复功能
     * @param replyInfoVO 回复的对象
     * @return ResultAjax
     */
    @RequestMapping("/doreply")
    public ResultAjax doReply(ReplyInfoVO replyInfoVO,HttpServletRequest request) {
        // 1. 效验参数
        if (replyInfoVO == null) {
            return ResultAjax.fail(-1,"参数错误");
        }
        System.out.println(replyInfoVO.toString());
        // 2. 获取当前用户
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-2,"请先登录");
        }
        // 3. 组装数据
        ReplyInfo replyInfo = new ReplyInfo();
        replyInfo.setReply(replyInfoVO.getReply());
        replyInfo.setUser(userinfo.getUsername());
        // 4. 根据 toUser 和 discuss 查到评论 id 并加到回复对象中
        Integer did = articleService.getIdByUserAndDiscuss(replyInfoVO);
        replyInfo.setDid(did);
        // 5. 把对象存至数据库,返回
        int result = articleService.addReply(replyInfo);
        return ResultAjax.succ(result);
    }


    /**
     * 根据阅读量推荐
     * @return ResultAjax
     */
    @RequestMapping("/recommend")
    public ResultAjax recommend() {
        List<Articleinfo> articleinfoList =  articleService.getArticleAll();
        if (articleinfoList == null) {
            return ResultAjax.fail(-1,"没有书籍");
        }
        for (int i = 0; i < articleinfoList.size(); i++) {
            if (articleinfoList.get(i).getContent().length() > _DESC_LENGTH) {
                articleinfoList.get(i).setContent(articleinfoList.get(i).getContent().substring(0,_DESC_LENGTH));
            }
        }
        // 根据 阅读量排序
        Collections.sort(articleinfoList, new ArticleComparator());
        if (articleinfoList.size() < 3) {
            return ResultAjax.succ(articleinfoList);
        }
        List<Articleinfo> list = new ArrayList<>();
        list.add(articleinfoList.get(0));
        list.add(articleinfoList.get(1));
        list.add(articleinfoList.get(2));
        return ResultAjax.succ(list);
    }






}
